﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using NBusiness.Utilities;
using System.Reflection;

namespace NBusiness.CodeDom.Services
{
    [Serializable]
    public class TypeData : MemberData
    {        
        public string AssemblyName { get; set; }

        public string Version { get; set; }

        public string Path { get; set; }

        public byte[] PublicKeyToken { get; set; }

        public CultureInfo Culture { get; set; }

        public TypeData[] Signature { get; set; }

        public TypeData(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            Name = type.Name;
            FullName = type.FullName;
            AssemblyName = type.Assembly.GetName().Name;
            PublicKeyToken = type.Assembly.GetName().GetPublicKeyToken();
            Culture = type.Assembly.GetName().CultureInfo;
            Version = type.Assembly.GetName().Version.ToString();
            Path = type.Assembly.Location;
        }

        public TypeData()
        {
            Culture = CultureInfo.InvariantCulture;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(FullName);

            if(!string.IsNullOrEmpty(AssemblyName))
            {
                sb.Append(", ");
                sb.Append(AssemblyName);
            }

            // If at least one of these fields is available then display
            // the full type name, otherwise go with a partial and hope for the best.
            if (!string.IsNullOrEmpty(Version) ||
                Culture != null ||
                PublicKeyToken != null)
            {
                if (!string.IsNullOrEmpty(Version))
                {
                    sb.Append(", Version=");
                    sb.Append(Version);
                }

                sb.Append(", Culture=");
                if (Culture != null && !Culture.Equals(System.Globalization.CultureInfo.InvariantCulture))
                    sb.Append(Culture.ToString());
                else sb.Append("neutral");

                sb.Append(", PublicKeyToken=");
                if (PublicKeyToken != null && PublicKeyToken.Length > 0)
                    sb.Append(BitConverter.ToString(PublicKeyToken).Replace("-", "").ToLower());
                else
                    sb.Append("null");
            }

            return sb.ToString();
        }

        public override bool Equals(object obj)
        {
            return obj.ToString() == ToString();
        }

        public static bool operator ==(Type type, TypeData data)
        {
            return type.ToString() + ", " + type.Assembly.ToString() == data.ToString();
        }

        public static bool operator !=(Type type, TypeData data)
        {
            return type.ToString() + ", " + type.Assembly.ToString() != data.ToString();
        }
    }
}
